SORACOM GPSマルチユニットをAWS IoT Coreに接続して、バッテリー低残量の通知を受け取る
GPSマルチユニットSORACOM Editionをバッテリー駆動で使っているのですが、バッテリー残量が気になるのです。
SORACOM Lagoonを使えばバッテリー残量のアラート通知ができますが、せっかくなのでAWS IoT Coreに接続して、バッテリーの低残量を通知する仕組みを作ってみました。
おすすめの方
- GPSマルチユニットSORACOM Editionのバッテリー低残量を通知したい方
- SORACOM FunnelでAWS IoT Coreにデータを送信したい方
- AWS IoT Eventsについて知りたい方
- AWS IoT EventsをCloudFormationで作成したい方
SORACOM Funnel用のIAMユーザを発行する
CloudFormationテンプレート(IAMユーザ)
特定のトピックに対して、iot:Publish
できる権限のみを付与しています。
AWSTemplateFormatVersion: 2010-09-09 Description: IAM User for SORACOM Funnel Resources: # SORACOM Funnel用のIAMユーザ SoracomFunnelUser: Type: AWS::IAM::User Properties: UserName: "soracom-funnel-user" # IAMユーザに付与するIAMポリシー SoracomFunnelUserPolicy: Type: AWS::IAM::Policy Properties: PolicyName: "soracom-funnel-user-policy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "iot:Publish" Resource: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topic/soracom/gps-multiunit/*" Users: - !Ref SoracomFunnelUser
デプロイ
aws cloudformation deploy \ --template-file iam_user.yml \ --stack-name SORACOM-Funnel-IAM-User-Stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
アクセスキーを取得
aws iam create-access-key \ --user-name soracom-funnel-user
SORACOM Funnelを設定してAWS IoT Coreにデータ送信する
SORACOMにAWS認証情報を登録
SORACOM Webコンソールにアクセスし、右上のメニューにある「セキュリティ」を選択します。
続いて、「認証情報ストア」にある「認証情報を登録」を選択します。
種別は「AWS認証情報」を選択し、さきほど取得したアクセスキーを貼り付けて登録します。
AWS IoT Coreエンドポイント取得
下記コマンドで取得できます。
aws iot describe-endpoint \ --endpoint-type iot:Data-ATS
SORACOM Funnelの設定入力
メニューの「SIMグループ」からGPSマルチユニットのSIMグループを選択します。
SORACOM Funnelの設定を行います。
項目 | 内容 |
---|---|
転送先サービス | AWS IoT |
転送先URL | xxxxx.iot.ap-northeast-1.amazonaws.com/soracom/gps-multiunit/#{imsi} |
認証情報 | さきほど登録した認証情報 |
送信データ形式 | JSON |
AWSs IoT Coreでテスト
IoT Coreの「テスト」にアクセスして、下記トピックをサブスクライブします。
- soracom/gps-multiunit/+
しばらく待つとデータが送信されてきました!!!
JSON内容は下記です(一部マスクしています)
{ "operatorId": "xxx", "timestamp": 1612846193590, "destination": { "resourceUrl": "xxx.iot.ap-northeast-1.amazonaws.com/soracom/gps-multiunit/#{imsi}", "service": "aws-iot", "provider": "aws" }, "credentialsId": "funnel-aws-iot-core", "payloads": { "bat": 3, "temp": 25.3, "rs": 0, "lon": 135, "y": null, "humi": 25.2, "lat": 45, "x": null, "z": null, "type": 1 }, "sourceProtocol": "udp", "imsi": "111111111111111" }
ここのbat
を監視し、必要に応じて通知すればOKですね。
なお、ペイロードの詳細はこちらに記載があります。
GPSマルチユニットの低残量を通知する
バッテリー残量による状態遷移
bat
の範囲は「-1,1〜3(-1は充電中)」です。今回は、bat=1
がバッテリー低残量とみなして通知する仕組みを作成します。
状態 | 遷移条件 |
---|---|
BatteryHigh | bat==3 |
BatteryLow | bat==1 |
状態管理はAWS IoT Eventsで行います。
CloudFormationテンプレート
- メール通知用のSNSトピック
- IoTルール
- IoTルール用のIAMロール
- IoT Eventsの入力情報
- IoT Eventsの探知器モデル
- IoT Eventsの探知器モデル用のIAMロール
- IoT Eventsの探知器モデル用のCloudWatchロググループ
AWSTemplateFormatVersion: 2010-09-09 Description: IoT Events for SORACOM GPS Multiunit Notify Battery Low Resources: SoracomGpsMultiunitTopicRule: Type: AWS::IoT::TopicRule Properties: RuleName: soracom_gps_multiunit_topic_rule TopicRulePayload: AwsIotSqlVersion: "2016-03-23" RuleDisabled: false Sql: >- SELECT topic(3) as imsi, payloads.bat FROM 'soracom/gps-multiunit/+' WHERE payloads.type <> -1 Actions: - IotEvents: InputName: !Ref SoracomGpsMultiunitEventsInput RoleArn: !GetAtt SoracomGpsMultiunitTopicRuleRole.Arn SoracomGpsMultiunitNotifyBatteryTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: sample@example.com Protocol: email SoracomGpsMultiunitTopicRuleRole: Type: AWS::IAM::Role Properties: RoleName: soracom-gps-multiunit-topic-rule-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: iot.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSIoTEventsFullAccess SoracomGpsMultiunitEventsInput: Type: AWS::IoTEvents::Input Properties: InputName: SoracomGpsMultiunitInputData InputDefinition: Attributes: - JsonPath: imsi - JsonPath: bat SoracomGpsMultiunitBatteryDetectorModel: Type: AWS::IoTEvents::DetectorModel Properties: DetectorModelName: soracom-gps-multiunit-battery-detector-model Key: imsi EvaluationMethod: BATCH RoleArn: !GetAtt SoracomGpsMultiunitBatteryDetectorModelRole.Arn DetectorModelDefinition: InitialStateName: BatteryHigh States: - StateName: BatteryHigh OnInput: TransitionEvents: - EventName: to_battery_low NextState: BatteryLow Condition: $input.SoracomGpsMultiunitInputData.bat == 1 - StateName: BatteryLow OnEnter: Events: - EventName: send-mail-to-battery-low Actions: - Sns: TargetArn: !Ref SoracomGpsMultiunitNotifyBatteryTopic Payload: Type: STRING ContentExpression: "'バッテリーが低残量になりました。対象デバイス: ${$input.SoracomGpsMultiunitInputData.imsi}'" OnInput: TransitionEvents: - EventName: to_battery_high NextState: BatteryHigh Condition: $input.SoracomGpsMultiunitInputData.bat == 3 OnExit: Events: - EventName: send-mail-to-battery-high Actions: - Sns: TargetArn: !Ref SoracomGpsMultiunitNotifyBatteryTopic Payload: Type: STRING ContentExpression: "'バッテリー残量が復旧しました。。対象デバイス: ${$input.SoracomGpsMultiunitInputData.imsi}'" SoracomGpsMultiunitBatteryDetectorModelRole: Type: AWS::IAM::Role Properties: RoleName: soracom-gps-multiunit-battery-detector-model-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: iotevents.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSNSFullAccess
デプロイ
aws cloudformation deploy \ --template-file notify_soracom_gps_multiunit_battery_low.yml \ --stack-name Notify-SORACOM-GPS-Multiunit-Battery-Low-Stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
デプロイされた探知器モデルを確認する
無事にできました!
動作確認
BatteryHighになっている
さっそくディテクターの様子を見てみると、BatteryHigh状態になっていました。
バッテリー低残量が通知された
しばらく放置していると、バッテリー低残量が通知されました。
ディテクターの状態もBatteryLowになっています。
充電すると、バッテリー残量の復旧通知がきた
充電してしばらく待つと、バッテリー残量の復旧通知がきました。
ディテクターの状態もBatteryHighに戻りました。
おまけ
SORACOM Harvestでbat
を確認すると、下記のような状態でした。(送信間隔は5分)
bat | 時間 |
---|---|
2 | 約1時間半 |
1 | 約4時間半 |
今回はbat==1
で低残量を通知しましたが、あまり差がないので、bat==2
で通知しても良さそうですね。